package com.zalbert.woolgather

import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import com.lxj.xpopup.XPopup
import com.zalbert.de.viewBinding
import com.zalbert.log.LogD
import com.zalbert.log.TLog.threadInfo
import com.zalbert.woolgather.databinding.ActivityCoroutinesBinding
import com.zalbert.woolgather.databinding.ActivityMainBinding
import kotlinx.coroutines.*


class CoroutinesActivity : AppCompatActivity() {
    var mSb = StringBuffer()
    val fuckA = arrayOf("派发器Dispatcher", "Unconfined规则", "等待一个作业", "条目4")
    var selectPosition = 0
    val viewBinding by viewBinding(ActivityCoroutinesBinding::bind)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_coroutines)
        viewBinding.run {
            tvRunProject.text = fuckA[selectPosition]
            btnChange.setOnClickListener {
                XPopup.Builder(this@CoroutinesActivity) //.maxWidth(600)
                    .asCenterList(
                        "选择运行的方法", fuckA
                    ) { position, text ->
                        clear()
                        findViewById<TextView>(R.id.tv_run_project).text = text
                        selectPosition = position
                    }
                    .show()
            }
            btnStart.setOnClickListener {
                when (selectPosition) {
                    0 -> {
                        startDispatchers()
                    }
                    1 -> {
                        startUnconfined()
                    }
                    2 -> {
                        startWait()
                    }
                }
            }
            btnClear.setOnClickListener {
                clear()
            }
        }

    }

    private fun clear() {
        mSb = StringBuffer()
        lifecycleScope.launch(Dispatchers.Main) {
            findViewById<TextView>(R.id.tv_text).text = mSb
        }
    }

    /**
     * 派发器Dispatcher
     */
    fun startDispatchers() = runBlocking {
        launch { // context of the parent, main runBlocking coroutine
            appendLn("Main runBlocking : I'm working in thread ${threadInfo()}")
        }
        launch(Dispatchers.Unconfined) { // not confined -- will work with main thread
            appendLn("Unconfined : I'm working in thread ${threadInfo()}")
        }
        launch(Dispatchers.Default) { // will get dispatched to DefaultDispatcher
            appendLn("Default : I'm working in thread ${threadInfo()}")
        }
        launch(newSingleThreadContext("MyOwnThread")) { // will get its own new thread
            appendLn("NewSingleThreadContext : I'm working in thread ${threadInfo()}")
        }
    }


    fun startUnconfined() = runBlocking {
        launch(Dispatchers.Unconfined) { // 非受限 -- 将会在主线程中执行
            appendLn("Unconfined      : I'm working in thread ${threadInfo()}")
            delay(500)
            appendLn("Unconfined      : After delay in thread ${threadInfo()}")
        }
        launch { // 使用父协程的上下文, 也就是 main 函数中的 runBlocking 协程
            appendLn("Main runBlocking: I'm working in thread ${threadInfo()}")
            delay(1000)
            appendLn("Main runBlocking: After delay in thread ${threadInfo()}")
        }
    }

    fun startWait() = runBlocking {
        val job = GlobalScope.launch { // 启动一个新协程并保持对这个作业的引用
            delay(1000L)
            appendLn("World!")
        }
        appendLn("Hello,")
//        job.join() // 等待直到子协程执行结束
    }


    private fun appendLn(msg: String) {
        mSb.append(msg).append("\n\n")
        Log.d("CoroutinesActivity", msg)
        /**
         * runBlocking会阻塞主线程，所以UI会在阻塞完毕后输出
         */
        lifecycleScope.launch(Dispatchers.Main) {
            findViewById<TextView>(R.id.tv_text).text = mSb
        }
    }
}